/*
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.util;

import java.util.function.Consumer;

/**
 * <p>一个迭代器覆盖一个集合，iterator取代了enumeration
 * 它比enumeration好的地方是
 * <p>允许在已经访问过的集合内，删除元素
 * <p> 增强方法的名字
 *
 * @param <E> the type of elements returned by this iterator
 * <p>E是迭代器返回的元素的类型
 * @author  Josh Bloch
 * @see Collection
 * @see ListIterator
 * @see Iterable
 * @since 1.2
 */
public interface Iterator<E> {
    /**
     * <p>返回这次迭代是否还有更多的元素，换言而之，如果返回true，那么调用next方法会返回一个元素
     * <p>如果返回false，next方法会报错
     * @return {@code true} if the iteration has more elements
     */
    boolean hasNext();

    /**
     * Returns the next element in the iteration.
     * <p>返回这次迭代的下一个元素，如果没有了，会报NoSuchElementException
     * @return the next element in the iteration
     * @throws NoSuchElementException if the iteration has no more elements
     */
    E next();

    /**
     * <p>在已经访问过的集合内，删除最后返回的元素
     * <p>这个方法只能在调用next方法后，被调用一次，一一对应，（不能调用1次next，然后调用2次remove）
     * <p>如果被访问的集合被修改了（当这个迭代处于其他的过程而不是通过调用这个方法），这个方法的结果没有被定义
     * <p>例如在别的线程内，删除元素
     * <p>默认实现是不实现方法，抛出异常UnsupportedOperationException（代表着实现iterator接口的类，可以选择不实现这个方法）
     * @throws UnsupportedOperationException if the {@code remove}
     *         operation is not supported by this iterator
     *
     * @throws IllegalStateException if the {@code next} method has not
     *         yet been called, or the {@code remove} method has already
     *         been called after the last call to the {@code next}
     *         method
     */
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    /**
     * <p>对每个保留的元素执行给定的参数action的accept方法，直到所有的元素都被处理了或者action报错
     * <p>注意：第一个被执行的元素是下一次next返回的元素，而不是这个迭代器被新建时，第一次next的元素
     * <p>action以迭代的顺序被执行（如果顺序被设定了）
     * <p>被抛出的异常会被转发给调用者
     * <p>默认实现等价于
     * <pre>{@code
     *     while (hasNext())
     *         action.accept(next());
     * }</pre>
     *
     * @param action The action to be performed for each element
     * @throws NullPointerException if the specified action is null
     * @since 1.8
     */
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}
